#include <iostream>
#include <string>
#include <stdlib.h>
#include <cstring>
#include <unistd.h>
using namespace std;
bool get_method(string &method)
{
    char *p_method = getenv("METHOD");
    if (!p_method)
        return false;
    method = p_method;
    return true;
}
bool get_query_str(string &str)
{
    char *p_query_str = getenv("QUERY_STR");
    if (!p_query_str)
        return false;
    str = p_query_str;
    return true;
}
bool get_content(string &content)
{
    content.clear();
    char *p_body_size = getenv("CONTENT_LENGTH");
    unsigned long content_length = (p_body_size ? stoul(p_body_size) : 0);
    cerr << "content_length: " << content_length << endl;
    size_t left_size = content_length;
    char buffer[1024];
    while (left_size)
    {
        size_t load = left_size > sizeof(buffer) ? sizeof(buffer) : left_size;
        bzero(buffer, sizeof(buffer));
        cerr << "reading... " << load << endl;
        cin.read(buffer, load);
        int s_size = cin.gcount();
        cerr << s_size << endl;
        if (s_size <= 0)
        {
            cerr << strerror(errno) << endl;
            if (s_size != 0)
                cerr << "post read content error!" << endl;
            else
                cerr << "eof read; left_size: " << left_size << endl;
            break;
        }
        left_size -= s_size;
        content.append(buffer, s_size);
    }
    return left_size ? false : true;
}
int main()
{
    cerr << "___________CGI program_______________" << endl;
    string method;
    string query_str;
    string content;
    if (get_method(method) == false)
        return 1;
    cerr << method << endl;
    if (method == "GET")
    {
        if (get_query_str(query_str) == false)
            return 2;
        cerr << "query str:" << query_str << endl;
        cout << "<h1>query str</h1>:" << query_str << endl;
    }
    if (method == "POST")
    {
        if (get_content(content) == false)
        {
            return 3;
        }
        cerr << content;
        cout.write(content.c_str(), content.size());
        cerr << "writen" << endl;
    }
    return 0;
}